/*
 * Date：10/23/18 10:15 PM
 * Author: guomw
 *
 */

package org.elanfox.intellicommunity.biz.service.core.resident.impl;

import org.apache.commons.lang3.StringUtils;
import org.elanfox.intellicommunity.biz.dto.condition.ResidentCondition;
import org.elanfox.intellicommunity.biz.dto.resident.ResidentSaveDTO;
import org.elanfox.intellicommunity.biz.entity.equipment.CardPO_;
import org.elanfox.intellicommunity.biz.entity.resident.ResidentPO;
import org.elanfox.intellicommunity.biz.entity.resident.ResidentPO_;
import org.elanfox.intellicommunity.biz.entity.resident.UserPO;
import org.elanfox.intellicommunity.biz.entity.resident.UserPO_;
import org.elanfox.intellicommunity.biz.repository.resident.ResidentRepository;
import org.elanfox.intellicommunity.biz.service.core.resident.ResidentService;
import org.elanfox.intellicommunity.biz.service.core.resident.RoomService;
import org.elanfox.intellicommunity.biz.service.core.resident.UserService;
import org.elanfox.intellicommunity.common.ienum.UserEnums;
import org.elanfox.intellicommunity.data.base.base.AbstractSearchableCrudService;
import org.elanfox.intellicommunity.data.base.base.SpecificationAndSort;
import org.elanfox.intellicommunity.data.base.dto.BaseSaveDTO;
import org.elanfox.intellicommunity.data.base.dto.BaseSearchDTO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;

import javax.persistence.criteria.Predicate;
import java.util.ArrayList;
import java.util.List;

/**
 * 用户相关service
 *
 * @author loutianxi
 * @date 2019-12-05
 */
@Service
public class ResidentServiceImpl extends AbstractSearchableCrudService<ResidentPO, Integer> implements ResidentService {

    @Autowired
    private ResidentRepository repository;
    @Autowired
    private UserService userService;
    @Autowired
    private RoomService roomService;

    protected ResidentServiceImpl(ResidentRepository repository) {
        super(repository);
    }

    @Override
    protected SpecificationAndSort<ResidentPO> specificationAndSort(BaseSearchDTO condition) {
        ResidentCondition residentCondition = (ResidentCondition) condition;
        Specification<ResidentPO> specification = (root, query, cb) -> {
            List<Predicate> predicates = new ArrayList<>();
            if (StringUtils.isNotEmpty(residentCondition.getCardNo())) {
                predicates.add(cb.equal(root.get(ResidentPO_.user).get(UserPO_.card).get(CardPO_.cardNo), residentCondition.getCardNo()));
            }
            if (StringUtils.isNotEmpty(residentCondition.getName())) {
                predicates.add(cb.like(root.get(ResidentPO_.user).get(UserPO_.name), likeAll(residentCondition.getName())));
            }
            if (StringUtils.isNotEmpty(residentCondition.getRoomNumber())) {
                predicates.add(cb.like(root.get(ResidentPO_.user).get(UserPO_.roomNumber), likeAll(residentCondition.getRoomNumber())));
            }
            if (residentCondition.getDelFlag() != null) {
                predicates.add(cb.equal(root.get(ResidentPO_.user).get(UserPO_.DEL_FLAG), residentCondition.getDelFlag()));
            }
            return cb.and(predicates.toArray(new Predicate[predicates.size()]));
        };

        Sort sort = new Sort(Sort.Direction.DESC, "createTime");

        return new SpecificationAndSort<>(specification, sort);
    }

    @Override
    public ResidentPO save(BaseSaveDTO saveDTO) {
        ResidentSaveDTO residentSaveDTO = (ResidentSaveDTO) saveDTO;
//        RoomPO roomPO = roomService.findByRoomName(residentSaveDTO.getRoomNumber());
//        if (roomPO == null) {
//            throw new IllegalStateException("房间号不存在");
//        }
        ResidentPO residentPO = findById(residentSaveDTO.getUserId());
        if (residentPO == null) {
            residentPO = new ResidentPO();
            residentSaveDTO.setType(UserEnums.Type.RESIDENT);
        }else{
            residentSaveDTO.setType(residentPO.getUser().getUserType());
        }

        UserPO userPO = userService.save(residentSaveDTO);
        residentPO.setUser(userPO);
        return repository.save(residentPO);
    }

    @Override
    public List<ResidentPO> findByRoomNumber(String roomNumber) {
        return repository.findByUser_RoomNumberAndUser_DelFlagIsTrue(roomNumber);
    }
}
